<template>
    <div class="scale-mirror-container" @click="callback">
        <div
            ref="viewBox"
            :style="[{ backgroundImage: `url(${url})` }]"
            class="scale-mirror__wrap"
            @mouseenter="parentMouseenter"
            @mouseleave="parentMouseleave"
        >
            <!-- 鼠标移动的视口 -->
            <div
                v-show="isShow"
                ref="viewPort"
                :style="[
                    { width: viewPortInfo.width },
                    { height: viewPortInfo.height },
                    { left: `${view_left}px` },
                    { top: `${view_top}px` },
                ]"
                class="scale-mirror__view-port"
            ></div>
        </div>
        <!-- 放大图片区域 -->
        <div
            v-show="isShow"
            :style="[
                { left: `${big_picture_left}px` },
                { backgroundImage: `url(${url})` },
                { backgroundSize: `${viewBox_width * times}px ${viewBox_height * times}px` },
                { backgroundPosition: `-${view_left * times}px -${view_top * times}px` },
            ]"
            class="scale-mirror__big-picture"
        ></div>
    </div>
</template>
<!-- 图片-放大镜组件 -->
<!-- 
    使用：
        url：必传
-->
<script  lang="ts" setup>
    import { ref, toRefs, onMounted } from 'vue'
 
    const emits = defineEmits(['callback'])
    const props = defineProps({
        // 图片地址
        url: {
            type: String,
            default: '',
        },
        // 放大倍数
        times: {
            type: [Number],
            default: 2,
        },
        // 放大视口 参数
        viewPortInfo: {
            type: Object,
            default: () => ({
                width: '200px',
                height: '200px',
            }),
        },
    })
 
    const { viewPortInfo, times, url } = toRefs(props)
    const isShow = ref(false)
    const view_left = ref(0)
    const view_top = ref(0)
    const viewBox = ref()
    const viewPort = ref()
    const big_picture_left = ref(0)
    const viewBox_width = ref(0)
    const viewBox_height = ref(0)
 
    // 移动处理函数
    const moveHandler = event => {
        const viewBoxInfo = viewBox.value.getBoundingClientRect()
        const width = parseFloat(viewPortInfo.value.width) // 网格宽
        const height = parseFloat(viewPortInfo.value.height) // 网格高
        const left = event.clientX - width / 2 - viewBoxInfo.left
        const top = event.clientY - height / 2 - viewBoxInfo.top
        const maxLeft = viewBoxInfo.width - width
        const maxTop = viewBoxInfo.height - height
        view_left.value = left <= 0 ? 0 : left >= maxLeft ? maxLeft : left
        view_top.value = top <= 0 ? 0 : top >= maxTop ? maxTop : top
    }
 
    const parentMouseenter = () => {
        isShow.value = true
        document.addEventListener('mousemove', moveHandler)
    }
 
    const parentMouseleave = () => {
        isShow.value = false
        document.removeEventListener('mousemove', moveHandler)
    }
 
    // 点击图片的回调
    const callback = () => {
        emits('callback', url.value)
    }
 
    onMounted(() => {
        const { width, height } = viewBox.value.getBoundingClientRect()
        big_picture_left.value = width + 4
        viewBox_width.value = width
        viewBox_height.value = height
    })
</script>
 
<style lang="scss" scope>
    .scale-mirror-container {
        position: relative;
        width: 100%;
        height: 100%;
        .scale-mirror__wrap {
            position: relative;
            min-width: 300px;
            min-height: 300px;
            width: 100%;
            height: 100%;
            background-repeat: no-repeat;
            background-size: 100% 100%;
            .scale-mirror__view-port {
                position: absolute;
                cursor: move;
                min-width: 200px;
                min-height: 200px;
                background-size: 2px 2px;
                background-image: linear-gradient(to right, rgba(178, 196, 241, 0.75) 1px, transparent 1px),
                    linear-gradient(to bottom, rgba(178, 196, 241, 0.75) 1px, transparent 1px);
                background-attachment: fixed;
            }
        }
        .scale-mirror__big-picture {
            position: absolute;
            top: 0;
            z-index: 1000;
            border: 1px solid #eeeeee;
            width: 600px;
            height: 600px;
            background-repeat: no-repeat;
            background-size: 100% 100%;
        }
    }
</style>